#!/bin/bash
export MSYS_NO_PATHCONV=1
export DOCKERHOST=${APPLICATION_URL-$(docker run --rm --net=host eclipse/che-ip)}
set -e

S2I_EXE=s2i
if [ -z $(type -P "$S2I_EXE") ]; then
  echo -e "The ${S2I_EXE} executable is needed and not on your path."
  echo -e "It can be downloaded from here: https://github.com/openshift/source-to-image/releases"
  echo -e "Make sure you extract the binary and place it in a directory on your path."
  exit 1
fi

SCRIPT_HOME="$(cd "$(dirname "$0")" && pwd)"

# =================================================================================================================
# Usage:
# -----------------------------------------------------------------------------------------------------------------
usage() {
  cat <<-EOF
    
      Usage: $0 [command] [options]
    
      Commands:
    
      build - Build the docker images for the project.
              You need to do this first, since the builds require
              a combination of Docker and S2I builds.
    
              You can build individual components as shown below, components that have dependencies
              will have these dependencies built too.
    
              Examples:
               - Build the web UI only.
    
                $0 build web

               - Build the web UI using a custom theme.
    
                $0 build web THEME=<theme-name> THEME_PATH=<absolute-path-to-themes-folder>
         
              By default all containers that components comprise of, will be rebuilt.
    
                $0 build

              Containers:
                - web
                - solr
                - db
                - schema-spy
                - api
                - agent
    
      up -  Creates the application containers from the built images
            and starts the services based on the docker-compose.yml file.

            You can pass in a list of containers to start.  
            By default all containers will be started.
            
            The API_URL used by vcr-web can also be redirected.

            Examples:
            $0 start
            $0 start vcr-solr
            $0 start vcr-web
            $0 start vcr-web API_URL=http://docker.for.win.localhost:56325/api/v1
            $0 start vcr-api

      start - Same as up 
    
      scale/upscale - Same as start/up however starts multiple instances of the aca-py and api containers.

            Note that to run "scale" you need to update the docker-compose.yml file to REMOVE exposed ports
            from the vcr-api and vcr-agent containers.

            You also need to FIRST run `./manage start` to initialize the agent and wallet, then run
            `./manage stop` and then `./manage scale`.

      restart - Re-starts the application containers, 
                useful when updating one of the container images during development.

            You can pass in a list of containers to be restarted.  
            By default all containers will be restarted.
            
            The API_URL used by vcr-web can also be redirected.

            Examples:
            $0 start
            $0 start vcr-solr
            $0 start vcr-web
            $0 start vcr-web API_URL=http://docker.for.win.localhost:56325/api/v1
            $0 start vcr-api

      logs - Display the logs from the docker compose run (ctrl-c to exit).

      web-dev - Builds and runs a live development version of vcr-web, along with
                the required supporting components. Once started, the website is
                automatically compiled and updated in response to file modifications.
                To use a custom theme, use the THEME and THEME_PATH environment
                variables described in the build step.

      stop - Stops the services.  This is a non-destructive process.  The volumes and containers
             are not deleted so they will be reused the next time you run start.
    
      down - Brings down the services and removes the volumes (storage) and containers.
      rm - Same as down
    
      registerDids - Register the DIDs for the issuer services.
                     This is intended for development use.
    
                     Examples:
                     $0 registerDids seed=the_org_book_0000000000000000000
                     - This will register the DID using the provided seed with the locally running von-network instance.

      test-api - Runs the suite of vcr-api unit tests in a Docker container

EOF
  exit 1
}
# -----------------------------------------------------------------------------------------------------------------
# Default Settings:
# -----------------------------------------------------------------------------------------------------------------
DEFAULT_CONTAINERS="wallet-db vcr-db vcr-solr vcr-api vcr-agent schema-spy vcr-web rabbitmq vcr-worker echo-app"
# -----------------------------------------------------------------------------------------------------------------
# Functions:
# -----------------------------------------------------------------------------------------------------------------
function echoRed (){
  _msg=${1}
  _red='\e[31m'
  _nc='\e[0m' # No Color
  echo -e "${_red}${_msg}${_nc}" >&2
}

function echoYellow (){
  _msg=${1}
  _yellow='\e[33m'
  _nc='\e[0m' # No Color
  echo -e "${_yellow}${_msg}${_nc}" >&2
}

function copyCustomTheme(){
  # Look for the theme within the context of the build ...
  themeFolder=$(find '../client/themes' -type d -name ${THEME})    
  if [ ! -z "${themeFolder}" ]; then
    echoYellow "Found the '${THEME}' theme within the build context; '${themeFolder}'"
  else
    echoYellow "The '${THEME}' theme was not found within the required build context."
    echoYellow "Copying the theme into the build context."
    sourceTheme="${THEME_PATH%/}/${THEME}"
    destinationTheme="../client/themes/${THEME}"
    cp -r "${sourceTheme}" "${destinationTheme}"
  fi

  echo "${destinationTheme}"
}

function cleanupCustomTheme(){
  customTheme=${1}
  if [ ! -z "${customTheme}" ] && [ -d "${customTheme}" ]; then
    echoYellow "Removing '${THEME}' from the build context."
    rm -rf "${customTheme}"
  fi  
}

build-web() {
  #
  # vcr-web
  #
  # The nginx-runtime image is used for the final runtime image.
  # The nodejs-build image is used to build the artifacts for the angular distribution.
  # The vcr-web image is copy of the nginx-runtime image complete with a copy of the build artifacts.
  #
  echo -e "\nBuilding nginx-runtime image ..."
  docker build -q \
    -t 'nginx-runtime' \
    -f './nginx-runtime/Dockerfile' './nginx-runtime/'

  # This image only exists to pre-create the npm cache directory
  # so it can be properly used as a volume, it doesn't apply to openshift
  echo -e "\nBuilding nodejs-build image ..."
  docker build -q \
    -t 'nodejs-build' \
    -f './nodejs-build/Dockerfile' './nodejs-build/'

  if [ -t 0 ]; then
    # color npm output in interactive terminal
	  NPM_COLOR="always"
  else
    NPM_COLOR="true"
  fi
  
  echo -e "\nBuilding vcr-web image ..."
  if [ -z "$THEME_PATH" ] && [ "$THEME" == "base" ]; then
    # No custom theme was specified
    ${S2I_EXE} build \
      --copy \
      -e "NPM_CONFIG_COLOR=${NPM_COLOR}" \
      -e "NPM_CONFIG_LOGLEVEL=timing" \
      -e "HTTP_PROXY=${HTTP_PROXY}" \
      -e "HTTPS_PROXY=${HTTPS_PROXY}" \
      -e "NG_BASE_HREF=${WEB_BASE_HREF}" \
      -e "NG_DEPLOY_URL=${WEB_DEPLOY_URL}" \
      -v "${COMPOSE_PROJECT_NAME}_vcr-npm-cache:/opt/app-root/src/.npm" \
      --runtime-image nginx-runtime \
      -a /opt/app-root/src/dist:app \
      '../client' \
      'nodejs-build' \
      'vcr-web'
  else
    # Use the custom theme
    customTheme=$(copyCustomTheme)
    ${S2I_EXE} build \
      --copy \
      -e "NPM_CONFIG_COLOR=${NPM_COLOR}" \
      -e "NPM_CONFIG_LOGLEVEL=timing" \
      -e "HTTP_PROXY=${HTTP_PROXY}" \
      -e "HTTPS_PROXY=${HTTPS_PROXY}" \
      -e "NG_BASE_HREF=${WEB_BASE_HREF}" \
      -e "NG_DEPLOY_URL=${WEB_DEPLOY_URL}" \
      -e "THEME=${THEME}" \
      -v "${COMPOSE_PROJECT_NAME}_vcr-npm-cache:/opt/app-root/src/.npm" \
      --runtime-image nginx-runtime \
      -a /opt/app-root/src/dist:app \
      '../client' \
      'nodejs-build' \
      'vcr-web'
    cleanupCustomTheme "${customTheme}"
  fi
}

build-web-dev() {
  #
  # vcr-web-dev
  # Alternative version of vcr-web for live development
  #
  echo -e "\nBuilding nodejs-build image ..."
  docker build -q \
    -t 'nodejs-build' \
    -f './nodejs-build/Dockerfile' './nodejs-build/'

  # NB: We build with DEV_MODE=true but run with DEV_MODE=false
  echo -e "\nBuilding vcr-web-dev image ..."
  if [ -z "$THEME_PATH" ] && [ "$THEME" == "base" ]; then
    # No custom theme path was specified
    ${S2I_EXE} build \
      --copy \
      -e "DEV_MODE=true" \
      -e "HTTP_PROXY=${HTTP_PROXY}" \
      -e "HTTPS_PROXY=${HTTPS_PROXY}" \
      -e "NG_BASE_HREF=${WEB_BASE_HREF}" \
      -e "NG_DEPLOY_URL=${WEB_DEPLOY_URL}" \
      -v "${COMPOSE_PROJECT_NAME}_vcr-npm-cache:/opt/app-root/src/.npm" \
      '../client' \
      'nodejs-build' \
      'vcr-web-dev'
  else
    # Use the custom theme
    customTheme=$(copyCustomTheme)
    ${S2I_EXE} build \
      --copy \
      -e "DEV_MODE=true" \
      -e "HTTP_PROXY=${HTTP_PROXY}" \
      -e "HTTPS_PROXY=${HTTPS_PROXY}" \
      -e "NG_BASE_HREF=${WEB_BASE_HREF}" \
      -e "NG_DEPLOY_URL=${WEB_DEPLOY_URL}" \
      -e "THEME=${THEME}" \
      -v "${COMPOSE_PROJECT_NAME}_vcr-npm-cache:/opt/app-root/src/.npm" \
      '../client' \
      'nodejs-build' \
      'vcr-web-dev'
    cleanupCustomTheme "${customTheme}"
  fi
}

build-solr() {
  #
  # vcr-solr
  #
  echo -e "\nBuilding solr-base image ..."
  docker build \
    https://github.com/bcgov/openshift-solr.git \
    -t 'solr-base'

  echo -e "\nBuilding solr image ..."
  ${S2I_EXE} build \
    --copy \
    -e "HTTP_PROXY=${HTTP_PROXY}" \
    -e "HTTPS_PROXY=${HTTPS_PROXY}" \
    '../server/solr/cores' \
    'solr-base' \
    'solr'
}

build-db() {
  #
  # db
  #
  echo -e "\nBuilding postgresql image ..."
  ${S2I_EXE} build \
    --copy \
    -e "HTTP_PROXY=${HTTP_PROXY}" \
    -e "HTTPS_PROXY=${HTTPS_PROXY}" \
    '../server/db/config' \
    'registry.access.redhat.com/rhscl/postgresql-10-rhel7:latest' \
    'postgresql'
}

build-schema-spy() {
  #
  # schema-spy
  #
  echo -e "\nBuilding schema-spy image ..."
  docker build \
    https://github.com/bcgov/SchemaSpy.git \
    -t 'schema-spy'
}

build-api() {
  #
  # vcr-api
  #
  BASE_IMAGE="bcgovimages/von-image:py36-1.7-ew-0-s2i"
  
  echo -e "\nBuilding vcr-api image from ${BASE_IMAGE}..."
  ${S2I_EXE} build \
    --copy \
    -e "HTTP_PROXY=${HTTP_PROXY}" \
    -e "HTTPS_PROXY=${HTTPS_PROXY}" \
    -e "PIP_NO_CACHE_DIR=" \
    -e "UPGRADE_PIP_TO_LATEST=true" \
    -v "${COMPOSE_PROJECT_NAME}_vcr-pip-cache:/home/indy/.cache/pip" \
    '../server/vcr-server' \
    "$BASE_IMAGE" \
    'vcr-api'

  # this is only required in Windows
  if [[ "$OSTYPE" == "msys" ]]; then
    echo -e "\nFixing file permissions in final vcr-api (django) image"
    docker build -q \
      --build-arg BASE_IMAGE='vcr-api:latest' \
      -t 'vcr-api' \
      -f './utils/Dockerfile.fixpermissions' './utils/'
  fi
}

build-agent() {
  #
  # agent
  #
  docker build -q \
    -t 'vcr-agent' \
    -f './vcr-agent/Dockerfile' './vcr-agent'

  # this is only required in Windows
  if [[ "$OSTYPE" == "msys" ]]; then
    echo -e "\nFixing file permissions in final agent image"
    docker build -q \
      --build-arg BASE_IMAGE='vcr-agent:latest' \
      -t 'vcr-agent' \
      -f './utils/Dockerfile.fixpermissions' './utils/'
  fi
}

build-echo-app() {
  #
  # echo-app
  #
  docker build -q \
    -t 'echo-app' \
    -f './echo-service/Dockerfile' '../echo-service'
}

build-all() {
  build-web
  build-solr
  build-db
  build-schema-spy
  build-api
  build-agent
  build-echo-app
}

configureEnvironment() {

  if [ -f .env ]; then
    while read line; do
      if [[ ! "$line" =~ ^\# ]] && [[ "$line" =~ .*= ]]; then
        export ${line//[$'\r\n']}
      fi
    done <.env
  fi

  for arg in "$@"; do
    # Remove recognized arguments from the list after processing.
    shift

    # echo "arg: ${arg}"
    # echo "Remaining: ${@}"

    case "$arg" in
      *=*)
        # echo "Exporting ..."
        export "${arg}"
        ;;
      *)
        # echo "Saving for later ..."
        # If not recognized, save it for later procesing ...
        set -- "$@" "$arg"
        ;;
    esac
  done

  seed=${INDY_WALLET_SEED:-00000000000000000000000000000000}

  if [ "$COMMAND" == "up" ] || [ "$COMMAND" == "start" ] || [ "$COMMAND" == "restart" ] || [ "$COMMAND" == "registerdids" ]; then
    if [ -z "$seed" ]; then
      echoError "You must provide a seed parameter. For example: seed=my_seed_000000000000000000000000."
      exit 1
    fi
  fi

  export COMPOSE_PROJECT_NAME="${COMPOSE_PROJECT_NAME:-vcr}"

  export INDY_WALLET_SEED=${seed}
  export STI_SCRIPTS_PATH=${STI_SCRIPTS_PATH:-/usr/libexec/s2i}
  export RUST_LOG=${RUST_LOG:-warn}
  export RUST_BACKTRACE=${RUST_BACKTRACE:-full}
  export DEBUG=${DEBUG:-true}

  # vcr-db
  export POSTGRESQL_DATABASE="THE_ORG_BOOK"
  export POSTGRESQL_USER="DB_USER"
  export POSTGRESQL_PASSWORD="DB_PASSWORD"
  export ENABLE_REALTIME_INDEXING=${ENABLE_REALTIME_INDEXING:-1}
  export UPDATE_CRED_TYPE_TIMESTAMP="${UPDATE_CRED_TYPE_TIMESTAMP:-true}"
  export CREATE_CREDENTIAL_CLAIMS="${CREATE_CREDENTIAL_CLAIMS:-true}"
  export PROCESS_INBOUND_CREDENTIALS="${PROCESS_INBOUND_CREDENTIALS:-true}"

  # wallet-db
  export WALLET_TYPE="postgres_storage"
  export WALLET_ENCRYPTION_KEY="key"
  export POSTGRESQL_WALLET_HOST="wallet-db"
  export POSTGRESQL_WALLET_PORT="5432"
  export POSTGRESQL_ADMIN_USER="postgres"
  export POSTGRESQL_ADMIN_PASSWORD="mysecretpassword"

  # schema-spy
  export DATABASE_SERVICE_NAME="vcr-db"
  export POSTGRESQL_DATABASE=${POSTGRESQL_DATABASE}
  export POSTGRESQL_USER=${POSTGRESQL_USER}
  export POSTGRESQL_PASSWORD=${POSTGRESQL_PASSWORD}

  # vcr-solr
  export CORE_NAME="credential_registry"

  # vcr-api
  export STARTUP_DELAY=${STARTUP_DELAY:-15}
  export APP_FILE=app-vonx.py
  export APP_CONFIG=${APP_CONFIG:-}
  # export APP_MODULE=api_indy.vcr_anchor.boot:init_app
  export API_HTTP_PORT=${API_HTTP_PORT:-8080}
  export EXPOSED_API_HTTP_PORT=${EXPOSED_API_HTTP_PORT:-8081}
  export DATABASE_SERVICE_NAME="vcr-db"
  export DATABASE_ENGINE=${DATABASE_ENGINE-postgresql}
  export DATABASE_NAME=${POSTGRESQL_DATABASE}
  export DATABASE_USER=${POSTGRESQL_USER}
  export DATABASE_PASSWORD=${POSTGRESQL_PASSWORD}
  export DEMO_SITE=${DEMO_SITE-True}
  export DJANGO_SECRET_KEY=wpn1GZrouOryH2FshRrpVHcEhMfMLtmTWMC2K5Vhx8MAi74H5y
  export DJANGO_DEBUG=True
  export DJANGO_LOG_LEVEL=${DJANGO_LOG_LEVEL-ERROR}
  export OPTIMIZE_TABLE_ROW_COUNTS=${OPTIMIZE_TABLE_ROW_COUNTS-}
  export INDY_DISABLED=${INDY_DISABLED-}
  export SOLR_SERVICE_NAME="vcr-solr"
  export SOLR_CORE_NAME=${CORE_NAME}
  export SKIP_INDEXING_ON_STARTUP=${SKIP_INDEXING_ON_STARTUP-}
  export GENESIS_URL=${GENESIS_URL-}
  export LEDGER_URL=${LEDGER_URL-http://$DOCKERHOST:9000}
  export LEDGER_PROTOCOL_VERSION=${LEDGER_PROTOCOL_VERSION-}
  export SQL_DEBUG=${SQL_DEBUG:-}
  export WEB_CONCURRENCY=${WEB_CONCURRENCY:-5}
  export APPLICATION_URL=${APPLICATION_URL-http://localhost:8080}
  export AGENT_ADMIN_API_KEY=${AGENT_ADMIN_API_KEY}

  export RECORD_TIMINGS=${RECORD_TIMINGS:-false}
  export TRACE_EVENTS=${TRACE_EVENTS:-false}
  export TRACE_PROOF_EVENTS=${TRACE_PROOF_EVENTS:-false}
  export TRACE_TARGET=${TRACE_TARGET:-log}

  # vcr-web
  export THEME=${THEME:-base}
  export THEME_PATH=${THEME_PATH-}
  export WEB_HTTP_PORT=${WEB_HTTP_PORT:-8080}
  export WEB_BASE_HREF=${WEB_BASE_HREF:-/}
  export WEB_DEPLOY_URL=${WEB_DEPLOY_URL:-/}
  export API_URL=${API_URL-http://vcr-api:8080/api/}
  export IpFilterRules='#allow all; deny all;'
  export RealIpFrom='127.0.0.0/16'
  export HTTP_BASIC_USERNAME=${HTTP_BASIC_USERNAME:-}
  export HTTP_BASIC_PASSWORD=${HTTP_BASIC_PASSWORD:-}

  # rabbitmq
  export RABBITMQ_USER="RABBITMQ_USER"
  export RABBITMQ_PASSWORD="RABBITMQ_PASSWORD"

  # agent
  export AGENT_ADMIN_PORT=8024
  export WEBHOOK_URL=${WEBHOOK_URL:-http://vcr-api:$API_HTTP_PORT}
  export HTTP_INTERFACE_PORT=8021
  export WS_INTERFACE_PORT=8023
  export AGENT_NAME="avcr.agent"
  export AGENT_ENDPOINT=${AGENT_ENDPOINT:-http://vcr-agent:$HTTP_INTERFACE_PORT}
  export AGENT_ADMIN_MODE="admin-insecure-mode"
  if [ ! -z "${AGENT_ADMIN_API_KEY}" ]; then
    AGENT_ADMIN_MODE="admin-api-key ${AGENT_ADMIN_API_KEY}"
  fi
  export AGENT_TIMING_MODE=""
  if [ "${RECORD_TIMINGS}" = "true" ]; then
    AGENT_TIMING_MODE="--timing"
  fi
  export AGENT_TRACE_MODE=""
  if [ "${TRACE_EVENTS}" = "true" ]; then
    AGENT_TRACE_MODE="--trace"
  fi
}

getInputParams() {
  ARGS=""

  for arg in $@; do
    case "$arg" in
    *=*)
      # Skip it
      ;;
    *)
      ARGS+=" $arg"
      ;;
    esac
  done

  echo ${ARGS}
}

getStartupParams() {
  CONTAINERS=""
  ARGS=""

  for arg in $@; do
    case "$arg" in
    *=*)
      # Skip it
      ;;
    -*)
      ARGS+=" $arg"
      ;;
    *)
      CONTAINERS+=" $arg"
      ;;
    esac
  done

  if [ -z "$CONTAINERS" ]; then
    CONTAINERS="$DEFAULT_CONTAINERS"
  fi

  echo ${ARGS} ${CONTAINERS}
}

deleteVolumes() {
  _projectName=${COMPOSE_PROJECT_NAME:-docker}

  echo "Stopping and removing any running containers ..."
  docker-compose down -v

  _pattern="^${_projectName}_\|^docker_"
  _volumes=$(docker volume ls -q | grep ${_pattern})

  if [ ! -z "${_volumes}" ]; then
    echo "Removing project volumes ..."
    echo ${_volumes} | xargs docker volume rm
  else
    echo "No project volumes exist."
  fi

  echo "Removing build cache ..."
  rm -Rf ../client/.cache
}

registerDids() {
  _seeds=${@}
  if [ -z "${_seeds}" ]; then
    echo -e \\n"registerDids; Missing parameter!"\\n
    exit 1
  fi

  for _seed in ${_seeds}; do
    registerDid ${_seed}
  done
}

registerDid() {
  _seed=${1}
  if [ -z "${_seed}" ]; then
    echo -e \\n"registerDid; Missing parameter!"\\n
    exit 1
  fi
  _seedJson=$(getSeedJson ${_seed})
  _ledgerUri=$(getLedgerRegistrationUrl)

  echo -e \\n"Registering ${_seed} with the ledger ..."
  curl -X POST \
    ${_ledgerUri} \
    -H 'content-type: application/json' \
    -d "${_seedJson}"
}

getSeedJson() {
  _seed=${1}
  if [ -z "${_seed}" ]; then
    echo -e \\n"getSeedJson; Missing parameter!"\\n
    exit 1
  fi

  echo "{\"seed\": \"${_seed}\"}"
}

generateSeeds() {
  echo ${INDY_WALLET_SEED}
}

getLedgerRegistrationUrl() {
  if [[ ("${LEDGER_URL}" == "http://${DOCKERHOST}:9000") && ("${DOCKERHOST}" != "localhost") ]]; then
    _ledgerUrl="http://localhost:9000"
  else
    _ledgerUrl="${LEDGER_URL}"
  fi

  echo "${_ledgerUrl}/register"
}

toLower() {
  echo $(echo ${@} | tr '[:upper:]' '[:lower:]')
}

echoError (){
  _msg=${1}
  _red='\033[0;31m'
  _nc='\033[0m' # No Color
  echo -e "${_red}${_msg}${_nc}" >&2
}

functionExists() {
  (
    if [ ! -z ${1} ] && type ${1} &>/dev/null; then
      return 0
    else
      return 1
    fi
  )
}
# =================================================================================================================

pushd ${SCRIPT_HOME} >/dev/null
COMMAND=$(toLower ${1})
shift || COMMAND=usage

case "${COMMAND}" in
  start|up)
    _startupParams=$(getStartupParams --force-recreate $@)
    configureEnvironment "$@"
    docker-compose up --scale vcr-worker=2 -d ${_startupParams} 
    docker-compose logs -f
    ;;
  scale|upscale)
    _startupParams=$(getStartupParams --force-recreate $@)
    configureEnvironment "$@"
    echo "NOTE make sure you have previously run $@ start to initialize the agent and wallet!!!"
    echo "NOTE make sure you have removed the port mapping in docker-compose.yml for vcr-api and vcr-agent!!!"
    echo "Press any key to continue or <CRTL-C> to abort"
    read anykey
    docker-compose up --scale vcr-worker=2 --scale vcr-api=6 --scale vcr-agent=5 -d ${_startupParams} 
    docker-compose logs -f
    ;;
  restart)
    _startupParams=$(getStartupParams $@)
    configureEnvironment "$@"
    docker-compose stop ${_startupParams}
    docker-compose up -d ${_startupParams}
    ;;
  logs)
    configureEnvironment "$@"
    docker-compose logs -f
    ;;
  web-dev)
    configureEnvironment "$@"
    [ -z "$SKIP_BUILD" ] && build-web-dev
    docker-compose run --rm --service-ports vcr-web-dev
    ;;
  stop)
    configureEnvironment
    docker-compose stop 
    ;;
  startdb)
    configureEnvironment "$@"
    docker-compose up -d wallet-db
    docker-compose logs -f
  ;;
  stopdb)
    configureEnvironment
    docker-compose stop wallet-db
  ;;
  rm|down)
    configureEnvironment
    deleteVolumes
    ;;
  registerdids)
    configureEnvironment "$@"
    registerDids $(generateSeeds)
    ;;
  build)
    configureEnvironment "$@"

    buildImage=$(toLower ${1})
    shift || buildImage=all
    buildImage=$(echo ${buildImage} | sed s~^vcr-~~)
    case "$buildImage" in
      *=*)
        buildImage=all
        ;;
    esac

    if functionExists "build-${buildImage}"; then
      eval "build-${buildImage}"
    else
      echoError "\nThe build function, build-${buildImage}, does not exist.  Please check your build parameters and try again.\nUse '-h' to get full help details."
      exit 1
    fi
    ;;
  shell)
    _inputParams=$(getInputParams $@)
    configureEnvironment "$@"
    docker-compose run --force-recreate vcr-api bash ${_inputParams}
    ;;
  api)
    _inputParams=$(getInputParams $@)
    configureEnvironment "$@"
    docker-compose run vcr-api python manage.py ${_inputParams}
    ;;
  test-api)
    DATABASE_ENGINE=${DATABASE_ENGINE-sqlite}
    DEMO_SITE=0
    ENABLE_REALTIME_INDEXING=0
    _inputParams=$(getInputParams $@)
    configureEnvironment "$@"
	  build-api
    docker-compose run --no-deps vcr-api bash -c "coverage run manage.py test ${_inputParams} && coverage report -m"
    ;;
  *)
    usage
    ;;
esac

popd >/dev/null